import { MessageOptions } from 'element-plus';
import { Ref } from 'vue';
import { getAssemblyMeta, getAssetBundleMeta } from './meta';
import { createDirectoryByUrl, isUrlExists } from './utils';

// 创建模块
export async function CreateModule(moduleName: string = ''): Promise<MessageOptions> {
    if (moduleName && !/^[A-Z][a-zA-Z0-9]*$/.test(moduleName)) {
        return { type: 'warning', message: '名称必须以大写字母开头且只包含字母数字' };
    }

    const moduleKeyword = moduleName ? 'module' : 'global';
    const moduleBundleName = moduleName ? `app-module-${moduleName}`.toLowerCase() : 'app-global';
    const moduleFileName = moduleName ? `AppModule${moduleName}` : 'AppGlobal';
    const moduleFileUrl = moduleName
        ? `db://assets/app-module/${moduleName}`
        : 'db://assets/app-global';

    let result = await createDirectoryByUrl({
        url: moduleFileUrl,
        subFolders: [
            {
                name: 'assembly',
                meta: getAssemblyMeta(moduleBundleName)
            },
            {
                name: 'assetbundle',
                meta: getAssetBundleMeta(moduleBundleName)
            }
        ]
    });

    if (!result) {
        return ({ type: 'error', message: '模块创建失败' });
    }

    result = await createDirectoryByUrl({
        url: `${moduleFileUrl}/assembly`,
        subFolders: [
            {
                name: 'content'
            },
            {
                name: moduleKeyword + '-view'
            },
            {
                name: moduleKeyword + '-model'
            },
            {
                name: moduleKeyword + '-controller'
            }
        ]
    });

    if (!result) {
        return ({ type: 'error', message: '模块创建失败' });
    }

    result = await createDirectoryByUrl({
        url: `${moduleFileUrl}/assetbundle`,
        subFolders: [
            {
                name: 'content'
            },
            {
                name: moduleKeyword + '-view'
            },
            {
                name: moduleKeyword + '-sound'
            }
        ]
    });
    if (!result) {
        return ({ type: 'error', message: '模块创建失败' });
    }

    const scriptUrl = `${moduleFileUrl}/assembly/${moduleFileName}.ts`;
    const scriptContent = moduleName
        ? `import { BaseModule, module } from 'db://xforge/base/BaseModule';

@module('${moduleName}')
export class Module extends BaseModule {

}`
        : `import { BaseGlobal, global } from 'db://xforge/base/BaseModule';

@global()
export class Global extends BaseGlobal {

}`;

    const createScriptResult = await Editor.Message.request('asset-db', 'create-asset', scriptUrl, scriptContent).catch(_ => null);
    if (!createScriptResult) {
        return ({ type: 'error', message: `${scriptUrl} 创建失败` });
    }
    Editor.Message.send('assets', 'twinkle', scriptUrl);

    return ({ type: 'success', message: '模块创建成功' });
}

// 创建model
function getModelScript(name: string) {
    return `import { BaseModel } from 'db://xforge/base/BaseModel';
export class ${name} extends BaseModel {

}`;
}
export async function createModelItem(inputName: Ref<string>, moduleName = ''): Promise<MessageOptions> {
    if (!inputName.value.trim()) {
        return { type: 'warning', message: '名称不能为空' };
    }

    if (!/^[A-Z][a-zA-Z0-9]*$/.test(inputName.value)) {
        return { type: 'warning', message: '名称必须以大写字母开头且只包含字母数字' };
    }

    if (!inputName.value.endsWith('Data') && !inputName.value.endsWith('Config')) {
        return { type: 'warning', message: '名称必须以Data或Config结尾' };
    }

    const scriptUrl = moduleName
        ? `db://assets/app-module/${moduleName}/assembly/module-model/${inputName.value}.ts`
        : `db://assets/app-global/assembly/global-model/${inputName.value}.ts`;
    if (isUrlExists(scriptUrl)) {
        return { type: 'warning', message: `${scriptUrl} 文件已存在` };
    }

    const createScriptResult = await Editor.Message.request('asset-db', 'create-asset', scriptUrl, getModelScript(inputName.value)).catch(_ => null);
    if (!createScriptResult) {
        return { type: 'error', message: `${scriptUrl} 创建失败` };
    }
    Editor.Message.send('assets', 'twinkle', scriptUrl);

    return { type: 'success', message: '创建成功' };
}

// 创建view
/**
 * 获取脚本内容
 */
function getViewScript(name: string) {
    return `import { _decorator, Node } from 'cc';
import { BaseView } from 'db://xforge/base/BaseView';
const { ccclass, property } = _decorator;

@ccclass('${name}')
export class ${name} extends BaseView {

    // 界面打开时的相关逻辑写在这(onShow可被多次调用-它与onHide不成对)
    onShow(params: any) {
    
    }

    // 界面关闭时的相关逻辑写在这(已经关闭的界面不会触发onHide)
    onHide() {
    
    }
}`;
}
export async function createViewItem(viewType: Ref<string>, inputName: Ref<string>, moduleName = ''): Promise<MessageOptions> {
    if (viewType.value.trim() === '') {
        return ({ type: 'warning', message: '请选择类型' });
    }

    if (!inputName.value.trim()) {
        return ({ type: 'warning', message: '名称不能为空' });
    }

    if (!/^[A-Z][a-zA-Z0-9]*$/.test(inputName.value)) {
        return ({ type: 'warning', message: '名称必须以大写字母开头且只包含字母数字' });
    }

    if (['page', 'paper', 'pop', 'top'].some(typeStr => inputName.value.toLowerCase().startsWith(typeStr))) {
        return ({ type: 'warning', message: '名称不能以Page、Paper、Pop、Top开头' });
    }

    // 创建脚本文件
    const className = `${viewType.value}${inputName.value}`;
    const scriptUrl = moduleName
        ? `db://assets/app-module/${moduleName}/assembly/module-view/${className}.ts`
        : `db://assets/app-global/assembly/global-view/${className}.ts`;

    if (isUrlExists(scriptUrl)) {
        return ({ type: 'warning', message: `${scriptUrl} 文件已存在` });
    }

    const createScriptResult = await Editor.Message.request('asset-db', 'create-asset', scriptUrl, getViewScript(className)).catch(_ => null);
    if (!createScriptResult) {
        return ({ type: 'error', message: `${scriptUrl} 创建失败` });
    }
    Editor.Message.send('assets', 'twinkle', scriptUrl);

    // 创建预制体文件
    const prefabUrl = moduleName
        ? `db://assets/app-module/${moduleName}/assetbundle/module-view/${className}.prefab`
        : `db://assets/app-global/assetbundle/global-view/${className}.prefab`;
    const sceneUrl = moduleName
        ? `db://assets/app-module/${moduleName}/assetbundle/module-view/${className}.scene`
        : `db://assets/app-global/assetbundle/global-view/${className}.scene`;

    if (isUrlExists(prefabUrl)) {
        return ({ type: 'warning', message: `${sceneUrl} 文件已存在` });
    }
    if (isUrlExists(prefabUrl)) {
        return ({ type: 'warning', message: `${prefabUrl} 文件已存在` });
    }

    // 创建view
    if (viewType.value === 'Page') {
        const createSceneResult = await Editor.Message.request('scene', 'execute-scene-script', {
            name: 'xforge',
            method: 'createScene',
            args: [className, sceneUrl]
        }).catch(_ => null);
        if (!createSceneResult) {
            return ({ type: 'error', message: `${sceneUrl} 创建失败` });
        }
        Editor.Message.send('assets', 'twinkle', sceneUrl);
    } else {
        const createPrefabResult = await Editor.Message.request('scene', 'execute-scene-script', {
            name: 'xforge',
            method: 'createPrefab',
            args: [className, prefabUrl]
        }).catch(_ => null);
        if (!createPrefabResult) {
            return ({ type: 'error', message: `${createPrefabResult} 创建失败` });
        }
        Editor.Message.send('assets', 'twinkle', prefabUrl);
    }

    return ({ type: 'success', message: '创建成功' });
}

// 创建controller
function getControllerScript(name: string) {
    return `import { BaseController } from 'db://xforge/base/BaseController';
export class ${name} extends BaseController {

}`;
}
export async function createControllerItem(inputName: Ref<string>, moduleName = ''): Promise<MessageOptions> {
    if (!inputName.value.trim()) {
        return ({ type: 'warning', message: '名称不能为空' });
    }

    if (!/^[A-Z][a-zA-Z0-9]*$/.test(inputName.value)) {
        return ({ type: 'warning', message: '名称必须以大写字母开头且只包含字母数字' });
    }

    if (inputName.value.toLowerCase().endsWith('controller')) {
        inputName.value += inputName.value.slice(0, inputName.value.length - 'controller'.length);
    }

    const className = inputName.value + 'Controller';
    const scriptUrl = moduleName
        ? `db://assets/app-module/${moduleName}/assembly/module-controller/${className}.ts`
        : `db://assets/app-global/assembly/global-controller/${className}.ts`;

    if (isUrlExists(scriptUrl)) {
        return ({ type: 'warning', message: `${scriptUrl} 文件已存在` });
    }

    const createScriptResult = await Editor.Message.request('asset-db', 'create-asset', scriptUrl, getControllerScript(className)).catch(_ => null);
    if (!createScriptResult) {
        return ({ type: 'error', message: `${scriptUrl} 创建失败` });
    }
    Editor.Message.send('assets', 'twinkle', scriptUrl);

    return ({ type: 'success', message: '创建成功' });
}

// 创建sound
export async function createSoundItem(soundType: Ref<string>, moduleName = ''): Promise<MessageOptions> {
    if (soundType.value.trim() === '') {
        return ({ type: 'warning', message: '请选择类型' });
    }

    const url = moduleName
        ? `db://assets/app-module/${moduleName}/assetbundle/module-sound`
        : 'db://assets/app-global/assetbundle/global-sound';

    const success = await createDirectoryByUrl({
        url: url,
        subFolders: [
            {
                name: soundType.value === '音乐目录' ? 'music' : 'effect'
            }
        ]
    });
    if (!success) {
        return ({ type: 'error', message: `${soundType.value} 创建失败` });
    }

    Editor.Message.send('assets', 'twinkle', url);
    return ({ type: 'success', message: `${soundType.value} 创建成功` });
}